package com.banmao;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.thread.ExecutorBuilder;
import cn.hutool.http.HtmlUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Attribute;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

@Slf4j(topic = "XManhua ==> ")
public class XManhua {

    protected static String comicName;

    protected static CountDownLatch XMAN_COUNTDOWNLATCH;

    private static final Scanner SCANNER = new Scanner(System.in);

    public static Scanner getScanner() {
        return SCANNER;
    }

    public static List<Map<String, String>> getMenu(String comicCode) {
        FakeBrowser fakeBrowser = FakeBrowser.builder()
                .host(Constant.HOST)
                .headers(Constant.BASE_HEADERS)
                .build();
        String html = fakeBrowser.sendGet("/" + comicCode + "/", null);
        List<Map<String, String>> allContent = getAllContent(html);
        String comicTitle = getComicTitle(html);
        comicName = StringUtils.isBlank(comicTitle) ? comicCode : comicTitle;
        return allContent;
    }

    public static List<Map<String, String>> getAllContent(String html) {
        LinkedList<Map<String, String>> contents = new LinkedList<>();
        Elements elements = Jsoup.parse(html).getElementsByAttributeValueContaining("class", "detail-list-form-item");
        for (Element element : elements) {
            for (Attribute attribute : element.attributes()) {
                String key = attribute.getKey();
                if ("href".equals(key)) {
                    String innerHtml = HtmlUtil.removeHtmlTag(element.html(), false, "span");
                    //log.debug("{} <--> {}", attribute.getValue(), innerHtml);
                    Map<String, String> map = MapUtil.builder(new HashMap<String, String>())
                            .put(attribute.getValue(), innerHtml).build();
                    contents.push(map);
                }
            }
        }
        return contents;
    }

    private static String getComicTitle(String html) {
        Elements elements = Jsoup.parse(html).getElementsByAttributeValueContaining("class", "detail-info-title");
        for (Element element : elements) {
            if (StringUtils.isNotBlank(element.html())) {
                return element.html();
            }
        }
        return null;
    }

    public static void downloadImages(List<Map<String, String>> menus, int leftIndex, int rightIndex) {

        leftIndex -= 1;

        rightIndex = Math.min(menus.size(), rightIndex);
        ArrayList<Integer> indexs = new ArrayList<>();

        for (; leftIndex < rightIndex; leftIndex++) {
            indexs.add(leftIndex);
        }

        downloadImages(menus, indexs);

    }

    private static void downloadImages(List<Map<String, String>> menus, List<Integer> downloadIndexs) {

        ThreadPoolExecutor threadPool = ExecutorBuilder.create()
                .setCorePoolSize(5)
                .setMaxPoolSize(5)
                .setKeepAliveTime(10, TimeUnit.SECONDS)
                .build();

        int chapters = downloadIndexs.size();
        XMAN_COUNTDOWNLATCH = new CountDownLatch(chapters);

        List<XManChapter> chapterList = new ArrayList<>();

        for (int downloadIndex : downloadIndexs) {
            if (downloadIndex >= menus.size()) {
                continue;
            }

            Map<String, String> map = menus.get(downloadIndex);
            for (String code : map.keySet()) {
                XManChapter chapter = XManChapter.builder()
                        .baseDirPath("static")
                        //.comicName(StringUtils.isBlank(comicName) ? comicCode : comicName)
                        .chapterTitle(map.get(code))
                        .chapterCode(code)
                        .chapterSuccess(new AtomicBoolean(true))
                        .indexInMap(downloadIndex)
                        .build();
                chapterList.add(chapter);
                threadPool.execute(chapter);
            }
        }


        try {
            XMAN_COUNTDOWNLATCH.await();
            threadPool.shutdown();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        ArrayList<Integer> failChapterIndexs = new ArrayList<>();
        for (XManChapter xManChapter : chapterList) {
            if (!xManChapter.getChapterSuccess().get()) {
                failChapterIndexs.add(xManChapter.getIndexInMap());
            }
        }

        if (failChapterIndexs.size() > 0) {
            System.out.printf("%d个章节失败 输入'Y'重试，或输入其他键退出\n", failChapterIndexs.size());

            String input = SCANNER.nextLine();
            while (StringUtils.isBlank(input)) {
                input = SCANNER.nextLine();
            }

            if ("Y".equalsIgnoreCase(input)) {
                downloadImages(menus, failChapterIndexs);
            }
        }

    }

}
